package daemon

import (
	"fmt"
	"io"
	"os"
	"os/exec"
	"strconv"
	"syscall"
	"time"
	"x1aCron/internal/global"
	"x1aCron/internal/scheduler"
)

func CreateDaemon() {
	// 创建管道
	r, w, err := os.Pipe()
	if err != nil {
		panic(err)
	}

	// 重新启动自身为后台进程
	cmd := exec.Command(os.Args[0])
	cmd.Env = append(os.Environ(), "DAEMON=1")

	cmd.ExtraFiles = []*os.File{w} // 管道写端传给子进程
	w.Close()

	logFile, err := os.OpenFile(global.LOG, os.O_CREATE|os.O_WRONLY|os.O_APPEND, 0644)
	if err != nil {
		fmt.Println("打开日志文件失败:", err)
		return
	}
	cmd.Stdout = logFile
	cmd.Stderr = logFile
	cmd.Stdin = nil
	cmd.SysProcAttr = &syscall.SysProcAttr{
		Setsid: true, // 脱离终端，成为新会话
	}
	if err = cmd.Start(); err != nil {
		fmt.Println("启动失败:", err)
		return
	}

	// 写入PID文件
	err = os.WriteFile(global.PID, []byte(strconv.Itoa(cmd.Process.Pid)), 0644)
	if err != nil {
		fmt.Println("写入PID文件失败:", err)
		return
	}
	fmt.Printf("\rx1aCorn, PID: %d time: %s\n", cmd.Process.Pid, time.Now().Format("2006-01-02 15:04:05"))

	buf := make([]byte, 1)
	_, err = r.Read(buf) // 阻塞，直到守护进程关闭写端
	if err == io.EOF {
		fmt.Printf("\rX1aCron started successfully, log file: %s\n", global.LOG)
	}
	r.Close()
}

func DaemonToDo() {
	// 守护进程
	done := make(chan struct{})
	go func() {
		<-done // 等待守护进程服务器启动完成
		f := os.NewFile(uintptr(3), "pipe")
		f.Close() // 立刻关闭，父进程会收到 EOF
	}()
	scheduler := scheduler.NewScheduler()
	scheduler.Run(done)
}
